home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / mailutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-31  |  8.8 KB  |  406 lines

  1. /*    General Mail Utilities
  2.  *    culled from other files to reduce unnecessary cross references.
  3.  *    This material is believed to be in the public domain.
  4.  */
  5. #include <stdio.h>
  6. #include <io.h>
  7. #include <fcntl.h>
  8. #include <ctype.h>
  9. #include "global.h"
  10. #include "config.h"
  11. #include "socket.h"
  12. #include "mailutil.h"
  13. #include "smtp.h"
  14. #include "files.h"
  15.  
  16.  
  17. extern FILE *subdir_fopen __ARGS((char *name, char *mode));
  18. extern char *nntp_name_expansion __ARGS((char *name));
  19.  
  20. /*     Jan 92    Bill Simpson
  21.  *        The following routines were combined from smtpserv.c,
  22.  *        pop3cli.c and nntpcli.c
  23.  */
  24.  
  25. #ifdef POP3CLIENT
  26.  
  27. /* Receive message from socket, copying to file.
  28.  * Returns number of lines received, -1 indicates error
  29.  */
  30. int
  31. recvmail(s,buf,len,fp,trace)
  32. int s;        /* Socket index */
  33. char *buf;    /* Line buffer */
  34. unsigned len;    /* Length of buffer */
  35. FILE *fp;    /* File to copy into */
  36. int trace;    /* to trace or not to trace */
  37. {
  38.     int lines = 0;
  39.  
  40.     while (recvline(s,buf,len) != -1) {
  41.         register char *p = buf;
  42.  
  43.         if (trace >= 4)
  44.             log(s,"<==%s", buf);
  45.  
  46.         /* check for end of message . or escaped .. */
  47.         if (*p == '.') {
  48.             if (*++p == '\n') {
  49.                 if (trace >= 3)
  50.                     log(s,"received %d lines", lines);
  51.                 return lines;
  52.             } else if ( *p != '.' ) {
  53.                 p--;
  54.             }
  55.         } else if (strncmp(p,"From ",5) == 0) {
  56.             /* for UNIX mail compatiblity */
  57.             (void) putc('>',fp);
  58.         }
  59.         /* Append to data file */
  60.         fputs(p,fp);
  61.         ++lines;
  62.     }
  63.     if ( trace >= 1 )
  64.         log(s,"receive error after %d lines", lines);
  65.     return -1;
  66. }
  67. #endif
  68.  
  69. #if (defined(POP2CLIENT) || defined(POP3CLIENT))
  70.  
  71. /* Copy from the work file into the mailbox.
  72.  * -1 indicates error
  73.  */
  74. int
  75. copymail(buf,len,wfp)
  76. char *buf;    /* Line buffer */
  77. unsigned len;    /* Length of buffer */
  78. FILE *wfp;    /* File to copy from */
  79. {
  80. FILE *mfp = NULLFILE;
  81. char *cp;
  82. int first = 0;
  83. struct list *cclist = NULLLIST;
  84. char from[256], to[256];
  85.  
  86.  
  87.     rewind (wfp);
  88.     from[0] = 0;
  89.     to[0] = 0;
  90.     while(fgets(buf,len,wfp) != NULLCHAR){
  91.         pwait(NULL);    /* give other processes time in long copy */
  92.         if (!first)    {
  93.             mfp = tmpfile();
  94.             if (!mfp)
  95.                 return -1;
  96.             putc ('>', mfp);
  97.             first = 1;
  98.         } else if (!strncmp(buf, "From ", 5))    {
  99.             addlist(&cclist,to,0,to);
  100.             fseek(mfp,0L,0);
  101.             pwait (NULL);        /* just to be nice to others */
  102.             if (to[0] && from[0])
  103.                 queuejob(mfp,Hostname,cclist,from);
  104.             del_list (cclist);
  105.             cclist = NULLLIST;
  106.             fclose (mfp);
  107.             from[0] = 0;
  108.             to[0] = 0;
  109.             mfp = tmpfile();
  110.             if (!mfp)
  111.                 return -1;
  112.             putc ('>', mfp);
  113.         }
  114.         fputs(buf,mfp);
  115.         
  116.  
  117.         if (!from[0] && !strncmp ("From: ", buf, 6))    {
  118.             rip (buf);
  119.             strcpy (from, &buf[6]);
  120.             if ((cp = strchr (from, ' ')) != 0)
  121.                 *cp = 0;
  122.         }
  123.         if (!to[0] && !strncmp ("To: ", buf, 4))    {
  124.             rip (buf);
  125.             strcpy (to, &buf[4]);
  126.             if ((cp = strchr (from, ' ')) != 0)
  127.                 *cp = 0;
  128.         }
  129.     }
  130.     addlist(&cclist,to,0,to);
  131.     fseek(mfp,0L,0);
  132.     pwait (NULL);        /* just to be nice to others */
  133.     if (to[0] && from[0])
  134.         queuejob(mfp,Hostname,cclist,from);
  135.     fclose(mfp);
  136.  
  137.     return 0;
  138. }
  139. #endif
  140.  
  141.  
  142. /*     Jan 92    Bill Simpson
  143.  *         The following routines were extracted from smtpserv.c
  144.  *        and smtpcli.c, since they are used from several places.
  145.  */
  146.  
  147. /* create mail lockfile */
  148. int
  149. mlock(dir,id)
  150. char *dir,*id;
  151. {
  152.     char lockname[FILE_PATH_SIZE];
  153.     int fd;
  154.     FILE *fp;
  155. #ifdef notdef
  156. /* This is NOT a good idea ! This prevents all mailfiles in subdirs
  157.  * to be accessed; thus no nntp access etc... - WG7J
  158.  */
  159.  
  160. #ifdef    MSDOS
  161.     if(strlen(id) > 8) {        /* truncate long filenames */
  162.         id[8] = '\0';
  163.         if(id[7] == '/')
  164.             id[7] = '\0';
  165.     }
  166. #endif
  167. #endif
  168.  
  169.     /* Try to create the lock file in an atomic operation */
  170.     sprintf(lockname,"%s/%s",dir,id);
  171.     nntp_name_expansion (lockname);
  172.     strcat(lockname,".lck");
  173. #ifdef        AMIGA
  174.     /* don't ask, really, just don't ask... I'd do file locking on
  175.      * an Amiga much more differently than this.
  176.      */
  177.     if(access(lockname, 0) == 0)
  178.         return -1;
  179. #endif
  180.     /* this is to create any needed directories for nntp-style areas */
  181.     fp = subdir_fopen (lockname, "w");
  182.     if (fp)    {
  183.         fclose (fp);
  184.         unlink (lockname);
  185.     }
  186. #ifndef TNOS_68K
  187.     if((fd = open(lockname, O_WRONLY|O_EXCL|O_CREAT,0600)) == -1)
  188. #else
  189.     if((fd = creat(lockname, S_ISHARE)) == -1)
  190. #endif
  191.         return -1;
  192.     close(fd);
  193.     return 0;
  194. }
  195.  
  196.  
  197. /* remove mail lockfile */
  198. int
  199. rmlock(dir,id)
  200. char *dir,*id;
  201. {
  202.     char lockname[FILE_PATH_SIZE];
  203.  
  204. #ifdef notdef /* See mlock() above - WG7J */
  205. #ifdef  MSDOS
  206.     if(strlen(id) > 8) {        /* truncate long filenames */
  207.         id[8] = '\0';
  208.         if(id[7] == '/')
  209.             id[7] = '\0';
  210.     }
  211. #endif
  212. #endif
  213.  
  214.     sprintf(lockname,"%s/%s.lck",dir,id);
  215.     return(unlink(lockname));
  216. }
  217.  
  218.  
  219. /* Given a string of the form <user@host>, extract the part inside the
  220.  * angle brackets and return a pointer to it.
  221.  */
  222. char *
  223. getname(cp)
  224. register char *cp;
  225. {
  226.     register char *cp1;
  227.  
  228.     if ((cp = strchr(cp,'<')) == NULLCHAR)
  229.         return NULLCHAR;
  230.     cp++;    /* cp -> first char of name */
  231.     if ((cp1 = strchr(cp,'>')) == NULLCHAR)
  232.         return NULLCHAR;
  233.     *cp1 = '\0';
  234.     return cp;
  235. }
  236.  
  237.  
  238. /*      Jan 92  Bill Simpson
  239.  *        The following routines were extracted from mailbox.c,
  240.  *        since they are used from several places.
  241.  */
  242.  
  243.  
  244. /* Parse a string in the "Text: Text <user@host>" or "Text: user@host (Text)"
  245.  * formats for the address user@host.
  246.  */
  247. char *
  248. getaddress(string,cont)
  249. char *string;
  250. int cont;        /* true if string is a continued header line */
  251. {
  252.     char *cp, *ap = NULLCHAR;
  253.     int par = 0;
  254.  
  255.     if((cp = getname(string)) != NULLCHAR) /* Look for <> style address */
  256.         return cp;
  257.  
  258.     cp = string;
  259.     if(!cont)
  260.         if((cp = strchr(string,':')) == NULLCHAR)    /* Skip the token */
  261.             return NULLCHAR;
  262.         else
  263.             ++cp;
  264.     for(; *cp != '\0'; ++cp) {
  265.         if(par && *cp == ')') {
  266.             --par;
  267.             continue;
  268.         }
  269.         if(*cp == '(')        /* Ignore text within parenthesis */
  270.             ++par;
  271.         if(par)
  272.             continue;
  273.         if(*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == ',') {
  274.             if(ap != NULLCHAR)
  275.                 break;
  276.             continue;
  277.         }
  278.         if(ap == NULLCHAR)
  279.             ap = cp;
  280.     }
  281.     *cp = '\0';
  282.     return ap;
  283. }
  284.  
  285.  
  286. char *Hdrs[] = {
  287.     "Approved: ",
  288.     "From: ",
  289.     "To: ",
  290.     "Date: ",
  291.     "Message-Id: ",
  292.     "Subject: ",
  293.     "Received: ",
  294.     "Sender: ",
  295.     "Reply-To: ",
  296.     "Status: ",
  297.     "X-BBS-Msg-Type: ",
  298.     "X-Forwarded-To: ",
  299.     "Cc: ",
  300.     "Return-Receipt-To: ",
  301.     "Apparently-To: ",
  302.     "Errors-To: ",
  303.     "Organization: ",
  304.     "Newsgroups: ",
  305.     "Path: ",
  306.     "X-BBS-Hold: ",
  307.     "X-Mail-Group: ",
  308.     NULLCHAR
  309. };
  310.  
  311.  
  312. /* return the header type */
  313. int
  314. htype(s)
  315. char *s;
  316. {
  317.     register char *p;
  318.     register int i;
  319.  
  320.     p = s;
  321.     /* check to see if there is a ':' before and white space */
  322.     while (*p != '\0' && *p != ' ' && *p != ':')
  323.         p++;
  324.     if (*p != ':')
  325.         return NOHEADER;
  326.  
  327.     for (i = 0; Hdrs[i] != NULLCHAR; i++) {
  328.         if (strnicmp(Hdrs[i],s,strlen(Hdrs[i])) == 0)
  329.             return i;
  330.     }
  331.     return UNKNOWN;
  332. }
  333.  
  334.  
  335. /* Read the rewrite file for lines where the first word is a regular
  336.  * expression and the second word are rewriting rules. The special
  337.  * character '$' followed by a digit denotes the string that matched
  338.  * a '*' character. The '*' characters are numbered from 1 to 9.
  339.  * Example: the line "*@*.* $2@$1.ampr.org" would rewrite the address
  340.  * "foo@bar.xxx" to "bar@foo.ampr.org".
  341.  * $H is replaced by our hostname, and $$ is an escaped $ character.
  342.  * If the third word on the line has an 'r' character in it, the function
  343.  * will recurse with the new address.
  344.  */
  345. char *
  346. rewrite_address(addr)
  347. register char *addr;
  348. {
  349. char *argv[10], buf[PLINELEN];
  350. register char *cp, *cp2, *retstr;
  351. register int cnt;
  352. register FILE *fp;
  353.  
  354.     if ((fp = fopen(Rewritefile,READ_TEXT)) == NULLFILE)
  355.         return NULLCHAR;
  356.  
  357.     memset((char *)argv,0,10*sizeof(char *));
  358.     while(fgets(buf,sizeof(buf),fp) != NULLCHAR) {
  359.         pwait (NULL);
  360.         if(*buf == '#')        /* skip commented lines */
  361.             continue;
  362.         if((cp = strpbrk(buf," \t")) == NULLCHAR) /* get the first word */
  363.             continue;
  364.         *cp = '\0';
  365.         if((cp2 = strchr(buf,'\t')) != NULLCHAR){
  366.             *cp = ' ';
  367.             cp = cp2;
  368.             *cp = '\0';
  369.         }
  370.         if(!wildmat(addr,buf,argv))
  371.             continue;        /* no match */
  372.         rip(++cp);
  373.         cp2 = retstr = (char *) callocw(1,PLINELEN);
  374.         while(*cp != '\0' && *cp != ' ' && *cp != '\t')
  375.             if(*cp == '$') {
  376.                 if(isdigit(*(++cp)))
  377.                     if(argv[*cp - '0'-1] != '\0')
  378.                         strcat(cp2,argv[*cp - '0'-1]);
  379.                 if(*cp == 'h' || *cp == 'H') /* Our hostname */
  380.                     strcat(cp2,Hostname);
  381.                 if(*cp == '$')    /* Escaped $ character */
  382.                     strcat(cp2,"$");
  383.                 cp2 = retstr + strlen(retstr);
  384.                 cp++;
  385.             }
  386.             else
  387.                 *cp2++ = *cp++;
  388.         for(cnt=0; argv[cnt] != NULLCHAR; ++cnt)
  389.             free(argv[cnt]);
  390.         fclose(fp);
  391.         /* If there remains an 'r' character on the line, repeat
  392.          * everything by recursing.
  393.          */
  394.         if(strchr(cp,'r') != NULLCHAR || strchr(cp,'R') != NULLCHAR) {
  395.             if((cp2 = rewrite_address(retstr)) != NULLCHAR) {
  396.                 free(retstr);
  397.                 return cp2;
  398.             }
  399.         }
  400.         return retstr;
  401.     }
  402.     fclose(fp);
  403.     return NULLCHAR;
  404. }
  405.  
  406.